package com.moxiao.yfjh.module.system.sms.utils;


import cn.hutool.json.JSONObject;
import com.alibaba.fastjson.JSON;
import com.aliyun.green20220302.Client;
import com.aliyun.green20220302.models.*;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.moxiao.yfjh.framework.common.util.json.JsonUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.*;

/**
 * @version 1.0
 * @Author zhk
 * @Date 2024/2/18 15:04
 **/
@Component
@Slf4j
public class GreenScanUtils {

    @Value("${aliyun.green.accessKeyId}")
    private String accessKeyId;

    @Value("${aliyun.green.secret}")
    private String secret;

    public static final List<String> imageLabelList = Collections.unmodifiableList(new ArrayList<String>() {
        private static final long serialVersionUID = 1L;

        {
            add("sexual_femaleShoulder");
            add("sexual_femaleLeg");
            add("sexual_maleTopless");
            add("political_politicalFigure_2");
            add("political_politicalFigure 3");
            add("political_prohibitedPerson 1");
            add("political_prohibitedPerson 2");
            add("polrtical_taintedCelebrlty");
            add("political_taintedcelebrity tii");
            add("polrtical_Chinamap");
            add("political_medicalOutfit");
            add("political_racism tii");
            add("wiolent_explosion");
            add("violent_burning");
            add("violent_crowding");
            add("religlon_christlanlty");
            add("religion_muslim");
            add("religion_ti");
            add("racism_til");
            add("object_landmark");
            add("object_rmb");
            add("object_foreignCurrency");
            add("object_wn");
            add("object_carcrash");
            add("religion_muslim");
            add("religion_ti");
            add("racism_ti");
            add("object_landmark");
            add("object_rmb");
            add("object_forelgnCurrency");
            add("object_wn");
            add("object_carcrash");
            add("object_candle");
            add("object_niood");
            add("inappropriate_drinking");
            add("Inapproprlate_tattoo");
            add("quallty_meaningless");
        }
    });
    /*** 杭州客户端 ***/
    private Client client;
    /*** 北京客户端 ***/
    private Client imgClient;
    /*** 上海客户端 ***/
    private Client shClient;

    /**
     * 杭州-客户端
     *
     * @throws Exception
     */
    @PostConstruct
    public void init() throws Exception {
        log.info("杭州-阿里云Api客户的初始化");
        Config config = new Config();
        config.setAccessKeyId(accessKeyId);
        config.setAccessKeySecret(secret);
        //接入区域和地址请根据实际情况修改
        config.setRegionId("cn-hangzhou");
        //config.setEndpoint("green-cip.cn-shanghai.aliyuncs.com");
        config.setEndpoint("green-cip.cn-hangzhou.aliyuncs.com");
        //连接时超时时间，单位毫秒（ms）。
        config.setReadTimeout(6000);
        //读取时超时时间，单位毫秒（ms）。
        config.setConnectTimeout(3000);
        client = new Client(config);
    }

    /**
     * 北京客户端
     */
    @PostConstruct
    public void initImg() throws Exception {
        log.info("北京-阿里云Api客户的初始化");
        Config config = new Config();
        config.setAccessKeyId(accessKeyId);
        config.setAccessKeySecret(secret);
        //接入区域和地址请根据实际情况修改
        config.setRegionId("cn-beijing");
        config.setEndpoint("green-cip.cn-beijing.aliyuncs.com");
        //连接时超时时间，单位毫秒（ms）。
        config.setReadTimeout(6000);
        //读取时超时时间，单位毫秒（ms）。
        config.setConnectTimeout(3000);
        imgClient = new Client(config);
    }

    /**
     * 上海客户端
     */
    @PostConstruct
    private void initShanghai() throws Exception {
        log.info("上海-阿里云Api客户的初始化");
        Config config = new Config();
        config.setAccessKeyId(accessKeyId);
        config.setAccessKeySecret(secret);
        //接入区域和地址请根据实际情况修改。
        config.setRegionId("cn-shanghai");
        config.setEndpoint("green-cip.cn-shanghai.aliyuncs.com");
        //连接时超时时间，单位毫秒（ms）。
        config.setReadTimeout(6000);
        //读取时超时时间，单位毫秒（ms）。
        config.setConnectTimeout(3000);

        shClient = new Client(config);
    }

    public Map greeTextScan(String content) throws Exception {
        // 创建RuntimeObject实例并设置运行参数。
        RuntimeOptions runtime = new RuntimeOptions();
        runtime.readTimeout = 10000;
        runtime.connectTimeout = 10000;
        //检测参数构造
        JSONObject serviceParameters = new JSONObject();
        serviceParameters.put("content", content);
        if (serviceParameters.get("content") == null || serviceParameters.getStr("content").trim().length() == 0) {
            log.info("文本审核内容为空");
            return null;
        }
        TextModerationRequest textModerationRequest = new TextModerationRequest();
        textModerationRequest.setService("comment_detection");
        textModerationRequest.setServiceParameters(serviceParameters.toString());

        Map<String, String> resultMap = new HashMap<>();
        try {
            // 调用方法获取检测结果。
            TextModerationResponse response = client.textModerationWithOptions(textModerationRequest, runtime);
            System.out.println(response);
            if (response != null) {
                if (500 == response.getStatusCode() || (response.getBody() != null && 500 == (response.getBody().getCode()))) {
                    // 切换北京客户端
                    response = imgClient.textModerationWithOptions(textModerationRequest, runtime);
                }
            }
            // 打印检测结果。
            if (response != null) {
                if (response.getStatusCode() == 200) {
                    TextModerationResponseBody result = response.getBody();
                    Integer code = result.getCode();
                    if (code != null && code == 200) {
                        TextModerationResponseBody.TextModerationResponseBodyData data = result.getData();
                        String labels = data.getLabels();
                        log.info("文本审核labels:{}，reason：{}", data.getLabels(), data.getReason());
                        if (Objects.equals(labels, "")) {
                            resultMap.put("suggestion", "pass");
                        } else {
                            resultMap.put("labels", data.getLabels());
                            resultMap.put("reason", data.getReason());
                        }
                        return resultMap;
                    } else {
                        log.info("文本审核不成功:{}", code);
                        resultMap.put("message", "文本审核不成功. code:");
                        resultMap.put("code", code.toString());
                        return resultMap;
                    }
                } else {
                    log.info("响应失败，status:{}", response.getStatusCode());
                    return null;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 一张阿里云oss图片可检测
     *
     * @param imageUrl
     * @return
     * @throws Exception
     */
    public Map imageScan(String imageUrl) throws Exception {
        // 杭州-接入区域和地址请根据实际情况修改。
        ImageModerationResponse response = invokeFunction(1, imageUrl);
        Map<String, String> resultMap = new HashMap<>();
        try {
            // 自动路由。
            if (response != null) {
                //区域切换到cn-beijing。
                if (500 == response.getStatusCode() || (response.getBody() != null && 500 == (response.getBody().getCode()))) {
                    // 接入区域和地址请根据实际情况修改。
                    response = invokeFunction(2, imageUrl);
                }
            }
            // 打印检测结果。
            if (response != null) {
                if (response.getStatusCode() == 200) {
                    ImageModerationResponseBody body = response.getBody();
                    log.info("检测结果:requestId：{}", body.getRequestId());
                    log.info("检测结果:code：{}", body.getCode());
                    log.info("检测结果:msg：{}", body.getMsg());
                    if (body.getCode() == 200) {
                        ImageModerationResponseBody.ImageModerationResponseBodyData data = body.getData();
                        List<ImageModerationResponseBody.ImageModerationResponseBodyDataResult> results = data.getResult();
                        for (ImageModerationResponseBody.ImageModerationResponseBodyDataResult result : results) {
                            String label = result.getLabel();
                            Float confidence = result.getConfidence();
                            if (Objects.equals(label, "nonLabel")) {
                                resultMap.put("suggestion", "pass");
                                resultMap.put("label", result.getLabel());
                                resultMap.put("confidence", result.getConfidence() + "");
                            } else {
                                log.info("检测结果:confidence：{}", confidence);
                                if (imageLabelList.contains(label)) {
                                    resultMap.put("suggestion", "pass");
                                    resultMap.put("label", result.getLabel());
                                    resultMap.put("confidence", result.getConfidence() + "");
                                } else {
                                    resultMap.put("label", result.getLabel());
                                    resultMap.put("confidence", result.getConfidence() + "");
                                }
                            }
                            return resultMap;
                        }
                    } else {
                        log.info("图片检测不成功，code:{}", body.getCode());
                        resultMap.put("message", "image moderation not success. code:");
                        resultMap.put("code", body.getCode().toString());
                        return resultMap;
                    }
                } else {
                    log.error("响应失败，status:{}", response.getStatusCode());
                }
            }
        } catch (Exception e) {
            log.error("图片检测失败-{}", e.getMessage());
        }
        return null;
    }

    public Map createVideoTaskScan(String videoUrl) throws Exception {
        Map<String, String> resultMap = new HashMap<>();
        JSONObject serviceParameters = new JSONObject();
        serviceParameters.put("url", videoUrl);
        VideoModerationRequest videoModerationRequest = new VideoModerationRequest();
        // 检测类型：videoDetection
        videoModerationRequest.setService("videoDetection");
        videoModerationRequest.setServiceParameters(JSON.toJSONString(serviceParameters));

        try {
            VideoModerationResponse response = shClient.videoModeration(videoModerationRequest);
            if (response.getStatusCode() == 200) {
                VideoModerationResponseBody result = response.getBody();
                System.out.println(JSON.toJSONString(result));
                System.out.println("requestId = " + result.getRequestId());
                System.out.println("code = " + result.getCode());
                System.out.println("msg = " + result.getMessage());
                Integer code = result.getCode();
                if (200 == code) {
                    VideoModerationResponseBody.VideoModerationResponseBodyData data = result.getData();
                    log.info("video检测成功，任务taskId:{}", data.getTaskId());
                    resultMap.put("taskId", data.getTaskId());
                    return resultMap;
                } else {
                    log.error("video检测失败，code:{}", code);
                }
            } else {
                log.error("未获取到响应数据，检测失败，status:{}", response.getStatusCode());
            }
        } catch (Exception e) {
            log.error("检测异常:{}", e.getMessage());
        }
        return null;
    }


    public Map videoScan(String taskId) throws Exception {
        Map<String, String> resultMap = new HashMap<>();
        JSONObject serviceParameters = new JSONObject();
        // 提交任务时返回的taskId。
        serviceParameters.put("taskId", taskId);
        VideoModerationResultRequest videoModerationResultRequest = new VideoModerationResultRequest();
        // 检测类型：videoDetection
        videoModerationResultRequest.setService("videoDetection");
        videoModerationResultRequest.setServiceParameters(JSON.toJSONString(serviceParameters));

        try {
            VideoModerationResultResponse response = shClient.videoModerationResult(videoModerationResultRequest);
            if (response.getStatusCode() == 200) {
                VideoModerationResultResponseBody result = response.getBody();
                if (200 == result.getCode()) {
                    VideoModerationResultResponseBody.VideoModerationResultResponseBodyData data = result.getData();
                    System.out.println(JSON.toJSONString(data));
                    VideoModerationResultResponseBody.VideoModerationResultResponseBodyDataAudioResult audioResult = data.getAudioResult();
                    VideoModerationResultResponseBody.VideoModerationResultResponseBodyDataFrameResult frameResult = data.getFrameResult();
                    if (CollectionUtils.isEmpty(audioResult.getAudioSummarys()) && Objects.equals(frameResult.getFrameNum(), 0)) {
                        resultMap.put("suggestion", "pass");
                        return resultMap;
                    } else {
                        resultMap.put("suggestion", "no");
                        return resultMap;
                    }
                } else {
//                    System.out.println("video moderation result not success. code:" + result.getCode());
                    log.error("video检测不成功，检测失败，code:{}", result.getCode());
                }
            } else {
//                System.out.println("response not success. status:" + response.getStatusCode());
                log.error("video检测失败，检测失败，status:{}", response.getStatusCode());
            }
        } catch (Exception e) {
            log.error("video检测异常:{}", e.getMessage());
        }
        return null;
    }


    public Map queryVideoScan(String taskId) throws Exception {
        Map<String, String> resultMap = new HashMap<>();
        com.aliyun.green20220302.models.VideoModerationResultRequest videoModerationResultRequest = new com.aliyun.green20220302.models.VideoModerationResultRequest();
        JSONObject serviceParameters = new JSONObject();
        // 提交任务时返回的taskId
        serviceParameters.put("taskId", taskId);
        videoModerationResultRequest.setService("videoDetection");
        videoModerationResultRequest.setServiceParameters(JSON.toJSONString(serviceParameters));
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            // 复制代码运行请自行打印 API 的返回值
            VideoModerationResultResponse response = shClient.videoModerationResultWithOptions(videoModerationResultRequest, runtime);
            System.out.println(JSON.toJSONString(response));
            if (response.getStatusCode() == 200) {
                VideoModerationResultResponseBody result = response.getBody();
                if (200 == result.getCode()) {
                    VideoModerationResultResponseBody.VideoModerationResultResponseBodyData data = result.getData();
                    System.out.println(JSON.toJSONString(data));
                    if (Objects.nonNull(data)) {
                        VideoModerationResultResponseBody.VideoModerationResultResponseBodyDataAudioResult audioResult = data.getAudioResult();
                        VideoModerationResultResponseBody.VideoModerationResultResponseBodyDataFrameResult frameResult = data.getFrameResult();
                        if (CollectionUtils.isEmpty(audioResult.getAudioSummarys()) && Objects.equals(frameResult.getFrameNum(), 0)) {
                            resultMap.put("suggestion", "pass");
                            return resultMap;
                        } else {
                            resultMap.put("suggestion", "no");
                            return resultMap;
                        }
                    }
                }
            }
        } catch (TeaException error) {
            // 此处仅做打印展示，请谨慎对待异常处理，在工程项目中切勿直接忽略异常。
            // 错误 message
            // 诊断地址
            com.aliyun.teautil.Common.assertAsString(error.message);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 此处仅做打印展示，请谨慎对待异常处理，在工程项目中切勿直接忽略异常。
            // 错误 message
            // 诊断地址
            com.aliyun.teautil.Common.assertAsString(error.message);

        }
        return null;
    }

    /**
     * 图片检测
     *
     * @param type     1：杭州，2：北京
     * @param imageUrl 图片地址
     */
    public ImageModerationResponse invokeFunction(Integer type, String imageUrl) throws Exception {
        // 创建RuntimeObject实例并设置运行参数
        RuntimeOptions runtime = new RuntimeOptions();
        // 检测参数构造。
        Map<String, String> serviceParameters = new HashMap<>();
        //公网可访问的URL。
        serviceParameters.put("imageUrl", imageUrl);
        //待检测数据唯一标识
        serviceParameters.put("dataId", UUID.randomUUID().toString());
        ImageModerationRequest request = new ImageModerationRequest();
        // 图片检测service：内容安全控制台图片增强版规则配置的serviceCode，示例：baselineCheck, profilePhotoCheck
        request.setService("profilePhotoCheck");
        request.setServiceParameters(JsonUtils.toJsonString(serviceParameters));
        ImageModerationResponse response = null;
        try {
            // 切换客户端
            if (type == 1) {
                response = client.imageModerationWithOptions(request, runtime);
            } else {
                response = imgClient.imageModerationWithOptions(request, runtime);
            }
            log.info("图片检测响应：-{}", response);
        } catch (Exception e) {
            log.error("图片检测响应：-{}", e.getMessage());
        }
        return response;
    }

}
